package com.slb.slnwp.common.utils;

import javax.servlet.http.HttpServletRequest;

/**
 * @author: joinly
 * @date: 2022/3/2 15:31
 * @desc:
 **/
public class IPUtil {

    private static final String LOCALHOST = "127.0.0.1";
    private static final String LOCALHOST_REMOTE = "0:0:0:0:0:0:0:1";
    private static final String UNKNOWN = "unknown";
    private static final String X_FORWARDED_FOR = "x-forwarded-for";
    private static final String PROXY_CLIENT_IP = "Proxy-Client-IP";
    private static final String WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP";
    private static final String HTTP_CLIENT_IP = "HTTP_CLIENT_IP";
    private static final String HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR";
    private static final String SPLIT_WORD = ",";

    /**
     * 获取目标主机的ip
     */
    public static String getRemoteHost(HttpServletRequest request) {
        // 只有在通过了HTTP代理或者负载均衡服务器时才会添加该项.
        String ip = request.getHeader(X_FORWARDED_FOR);
        if (isIPAddressNotEmpty(ip)) {
            // 用apache http做代理时一般会加上Proxy-Client-IP请求头.
            ip = request.getHeader(PROXY_CLIENT_IP);
        }
        if (isIPAddressNotEmpty(ip)) {
            // 用apache http做代理时web logic插件加上的头.
            ip = request.getHeader(WL_PROXY_CLIENT_IP);
        }
        if (isIPAddressNotEmpty(ip)) {
            // 是代理服务器发送的HTTP头.
            ip = request.getHeader(HTTP_CLIENT_IP);
        }
        if (isIPAddressNotEmpty(ip)) {
            // 简称XFF头，它代表客户端，也就是HTTP的请求端真实的IP.
            ip = request.getHeader(HTTP_X_FORWARDED_FOR);
        }
        if (isIPAddressNotEmpty(ip)) {
            // 未代理直接获取remoteAddr.
            ip = request.getRemoteAddr();
        }
        // localhost情况.
        if (LOCALHOST_REMOTE.equals(ip)) {
            ip = LOCALHOST;
        }
        // 真实ip为第一个非unknown的有效IP字符串.
        if (ip.split(SPLIT_WORD).length > 1) {
            ip = ip.split(SPLIT_WORD)[0];
        }
        return ip;
    }

    /**
     * 判断获取的ip不为空.
     */
    private static boolean isIPAddressNotEmpty(String ip) {
        return (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip));
    }

}
